mod primitive;
mod error;
mod request;
mod response;
mod utils;

use std::str::FromStr;

pub use primitive::*;
pub use error::*;

pub use request::*;
pub use response::*;

pub trait FromBytes where Self: Sized {
    type Err;
    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err>;
}

pub trait IntoBytes {
    fn to_bytes(&self) -> Vec<u8>;
}

impl<T> FromBytes for T 
where 
    T: FromStr<Err = HttpParseError>
{
    type Err = HttpParseError;
    fn from_bytes(bytes: &[u8]) -> Result<Self, HttpParseError> {
        let s = str::from_utf8(bytes)?;
        Self::from_str(s)
    }
}

impl<T> IntoBytes for T
where
    T: ToString,
{
    fn to_bytes(&self) -> Vec<u8> {
        self.to_string().into_bytes()
    }
}

pub trait FetchFromBytes where Self: Sized {
    type Err;
    fn fetch_from_bytes(bytes: &[u8]) -> Result<(&[u8], Self), Self::Err>;
}